home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 6158 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  3.1 KB

  1. Path: keats.ugrad.cs.ubc.ca!not-for-mail
  2. From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: Type casting
  5. Date: 22 Feb 1996 13:09:52 -0800
  6. Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
  7. Message-ID: <4gim30INNo4b@keats.ugrad.cs.ubc.ca>
  8. References: <4gfnmi$gsc@calvin.risq.qc.ca>
  9. NNTP-Posting-Host: keats.ugrad.cs.ubc.ca
  10.  
  11. In article <4gfnmi$gsc@calvin.risq.qc.ca>,
  12. Pierre Coulombe <pcoulomb@criq.qc.ca> wrote:
  13. >I have a problem with type casting in Visual C 1.5.
  14. >I expected the following program to print the value 254 for valI.
  15. >Instead it gives the output shown below.
  16. >Can someone tell me where is my mistake ?
  17. >
  18. >
  19. >******** Program *********
  20. >
  21. >#include <stdio.h>
  22. >#include <string.h>
  23. >#include <stdlib.h>
  24. >
  25. >typedef unsigned int UINT;
  26. >
  27. >#define MM_TO_UNITS 10.0F
  28. >
  29. >void main(void)
  30. >{
  31. >  float valF;
  32. >  UINT  valI;
  33. >  char string[80];
  34. >
  35. >  strcpy(string, "25.4");
  36.  
  37. Try char *string = "25.4". This is a waste.
  38.  
  39. >  valI =  (UINT) ((float) atof(string) * MM_TO_UNITS);
  40. >  printf("valI = %u\n", valI);
  41. >
  42. >  sprintf(string, "%f", (float) atof(string) * MM_TO_UNITS);
  43. >  printf("string = %s\n", string);
  44. >
  45. >  strcpy(string, "25.4");
  46. >  sprintf(string, "%u", (UINT) ((float) atof(string) * MM_TO_UNITS));
  47. >  printf("string = %s\n", string);
  48. >}
  49. >
  50. >
  51. >******** Output *********
  52. >
  53. >valI = 253
  54. >string = 254.000000
  55. >string = 253
  56.  
  57. Floating point numbers are stored in binary. Fractional numbers cannot be
  58. exactly represented unless they are powers of two. 25.4 is not a fractional
  59. power of two.
  60.  
  61. Here is 25.5 in binary:
  62.  
  63.     11001.1
  64.  
  65. When you convert that to the popular IEEE double-precision format, you get:
  66.  
  67.     1.10011 * 10 E 100
  68.  
  69. The sign is positive, hence the MSB is zero. The exponent of 4 gets added to an
  70. 11-bit bias, valued 1023:
  71.  
  72.     01111111111
  73. +    00000000100
  74. =    10000000011
  75.  
  76. So we have:
  77.  
  78. 0    10000000011    1001100000000000000000000000000000000000000000000000
  79.  
  80. Which is the 64-bit binary IEEE representation of 25.5. (This is not the only
  81. representation used on the various platforms that support C. It is not dictated
  82. by the language standard; I'm only using this to illustrate a point).
  83.  
  84.  
  85. Now, if you try finding the represenation for 25.4, you will get a repeating
  86. fraction, because 4/10 = 2/5 cannot be expressed in binary in a finite string of
  87. digits. Try doing the division
  88.  
  89.            0.011101
  90.         _______
  91.     101 | 10.01
  92.            1 01
  93.           -----
  94.                1 000
  95.              101
  96.            -----
  97.               0110
  98.               101
  99.              ----
  100.               00101
  101.  
  102. and we are back at 101. Hence 0.4(decimal) = 0.0111011101110111... (binary)
  103.  
  104. Due to the limited precision of the computer representation, the string for
  105. 25.4 has to get chopped off somwhere. The result is a number that is _less_
  106. than 25.4. When you multiply it by 10.0, you naturally get a number that is
  107. less than 254. It could be very close to 254, but no cigar. Hence when you cast
  108. it to an integer, it gets rounded down to 253.
  109.  
  110.  
  111. Try this:
  112.  
  113.     integer    = (int) (floating + 0.5)
  114.  
  115. That way you round up or down to the nearest integer. A number slightly less
  116. than 254 will turn into a number slightly less than 254.5, and hence round to
  117. 254.
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125. >
  126. >
  127. >
  128.  
  129.  
  130. -- 
  131.  
  132.